使用 let、var 和 const 宣告變數時分別在:作用域、初始化、重複宣告、重新賦值、提升時有不同的行為。
var 的作用域是全域或是在 function 中,var 宣告的變數會被提升到整個函式的頂端;
let 跟 const 則是區塊(block)作用域,這裡的 block 指的是 function 中或 if-else block 或 for-loop block,let 跟 const 只在它們所在的區塊內有效,使它們更具預測性,減少變數意外被覆蓋的可能性。
初始化就是指變數第一次的賦值。使用 var 跟 let 宣告的變數初始化可以不需要賦值;
使用 const 初始化則需要必須賦值,否則會拋出: SyntaxError: Missing initializer in const declaration 的錯誤。
var a;
let b;
const c; // SyntaxError: Missing initializer in const declaration
var 可以重複宣告,var 重複宣告時會覆蓋前面的變數; let 跟 const 則不可以。
var 跟 let 可以重新賦值; const 則不行,const 代表的是參考 (reference) 的不可變性 (immutable),當物件和陣列被指派給 const 時,參考的是其記憶體的位置,物件和陣列的內容屬性是可以修改的,但不能重新指派為新的物件或陣列。
var a = 1;
a = 2;
let b = 3;
b = 4;
const c = 5;
c = 6; //error 因為 'c' 為常數,所以無法指派至 'c'
const person = {
id:1 ;
name:'Ashley';
}
person.id = 2; //可以修改 person 的 id ,因為仍是參考同一個記憶體位置
console.log(person.id); // 2
person = {
id:5 ;
name:'Andy';
}; // TypeError: Assignment to constant variable. 這時試圖指派一個全新的物件給 person(也就代表參考的記憶位置改變了),因參考不可變性所以報錯。
var 宣告的變數會自動初始化,初始值為 undefined;let 跟 const 宣告的變數會進到暫時死區 (TDZ, Temporal Dead Zone),直到執行到宣告的那一行。
var a = "BFE";
let b = "bigfrontend";
console.log(this.a);
console.log(this.b);
var a = "BFE";
let b = "bigfrontend";
console.log(this.a); //"BFE"
console.log(this.b); //undefined
因為 var 的作用域是全域,var 的變數會被加到全域物件,在瀏覽器中是 window 物件,this 通常指向全域物件,因此 this.a 等同於 window.a 也就是"BFE"。
let 則是區塊的作用域,let 的變數無法被加到全域物件,因此 this.b 是 undefined。